﻿
/*
 * Javasript based on Functions(JBF) 1.03
 * 
 * Copyright(c) 2010, Fooxee (JA86.CN)
 *
 * JBF is licensed under the terms of the Open Source GPL 3.0(http://www.gnu.org/licenses/gpl.html) license. 
 * 
 * JBF's blog: http://www.cnblogs.com/JBF/
 * 
 * Created by Fooxee. at 2010.03.08  mailTo:hjccjun@163.com
 */

//DOM相关操作
JBF.Dom = JBF.dom = function(selector,context)
{
	//不知道为什么一定要创建一个副本 fucking
	var handle=JBF.createClass(JBF.Dom.fn);
	return new handle(selector,context);
};

JBF.Dom.fn={
	init : function(selector,context)
	{
		if (selector && selector.nodeType) 
		{
			this[0] = selector;
			this.el = this[0];
			this.style=this.el.style;
			return this;
		}
		if (typeof selector == "string" )
		{
			return JBF(document.getElementById(selector));
		}
		return this;
	},
	//获取并设置EL
	getEl : function(o)
	{
		if(!this.el)
		{
			if (o.nodeType) 
			{
				this[0] = o;
			}
			if (typeof o == "string" )
			{
				this[0]=document.getElementById(o);
			}
			this.el = this[0];
		}
		return this[0];
	},
	//隐藏
	hide : function()
	{
		var disattr=this.el.style.display;
		this.setAttrs({'JBF-DOM-DISPLAY' : JBF.isEmpty(disattr) ? '' : disattr});
		this.el.style.display='none';
		return this;
	},
	//显示
	show : function()
	{
		var disattr=this.getAttr('JBF-DOM-DISPLAY');
		if(JBF.isEmpty(disattr))
		{
			this.el.style.display = '';
		}
		else
		{
			this.el.style.display = (disattr == 'none' ? '' : disattr);
			this.removeAttr('JBF-DOM-DISPLAY');
		}
		return this;
	},
	//设置属性
	setAttrs:function(v)
	{
		v=JBF.isObject(v)?v:{};
		var el=this.el;
		JBF.each(v,function(p,idx)
		{
			el.setAttribute(p,v[p]);
		});
		return this;
	},
	//取得属性值
	getAttr:function(s)
	{
		if(JBF.isEmpty(s))
		{
			return null;	
		}
		return this.el.getAttribute(s);
	},
	//移除属性
	removeAttr:function(s)
	{
		if(JBF.isEmpty(s))
		{
			return;	
		}
		this.el.removeAttribute(s);
	},
	currentStyle:function()
	{
		return this.el.currentStyle || document.defaultView.getComputedStyle(this.el, null);
	},
	offset:function(el)
	{
		var left = 0, top = 0, elem = el || this.el;
		left=elem.offsetParent ? elem.offsetLeft + this.offset(elem.offsetParent).left  : elem.offsetLeft;
		top =elem.offsetParent ? elem.offsetTop + this.offset(elem.offsetParent).top : elem.offsetTop;
		return {top:top,left:left};
	},
	//css
	css:function(v)
	{
		if(JBF.isPrimitive(v) || JBF.isObject(v))
		{
			if(JBF.isObject(v))
			{
				var cs='';
				JBF.each(v,function(v,i,list)
				{
					cs +=v+':'+list[v]+' '
				});
				this.cssText(cs);
			}
			else
			{
				this.el.className=v;
			}
			return this;
		}
		else
		{
			return this.el.className;
		}
	},
	cssText:function(s)
	{
		if(JBF.isPrimitive(s))
		{
			this.el.style.cssText=s;
		}
		return this;
	},
	//html
	html:function(html)
	{
		if(JBF.isPrimitive(html))
		{
			this.el.innerHTML=html;
			return this;
		}
		else
		{
			return this.el.innerHTML;
		}
	},
	//value
	val:function(v)
	{
		if(JBF.isPrimitive(v))
		{
			this.el.value=v;
			return this;
		}
		else
		{
			return this.el.value;	
		}
	},
	wrap:function()
	{
		
	},
	//privte
	eventHandlers:{},
	//创建事件代理
	createEventProxy:function(fn,caller)
	{
		var thisObj=this;
		return function(event)
		{
			fn.call(thisObj,thisObj.eventFix(event || window.event),caller);
		};
	},
	//修正event(jquery)
	eventFix:function(event)
	{
		if ( event['expando'] == true ) 
			return event;

		// store a copy of the original event object
		// and "clone" to set read-only properties
		var originalEvent = event;
		event = { originalEvent: originalEvent };
		var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
		for ( var i=props.length; i; i-- ) 
			event[ props[i] ] = originalEvent[ props[i] ];

		// Mark it as fixed
		event['expando'] = true;

		// add preventDefault and stopPropagation since
		// they will not work on the clone
		event.preventDefault = function()
		{
			// if preventDefault exists run it on the original event
			if (originalEvent.preventDefault)
				originalEvent.preventDefault();
			// otherwise set the returnValue property of the original event to false (IE)
			originalEvent.returnValue = false;
		};
		event.stopPropagation = function()
		{
			// if stopPropagation exists run it on the original event
			if (originalEvent.stopPropagation) 
				originalEvent.stopPropagation();
			// otherwise set the cancelBubble property of the original event to true (IE)
			originalEvent.cancelBubble = true;
		};

		// Fix timeStamp
		event.timeStamp = event.timeStamp || +new Date();

		// Fix target property, if necessary
		if ( !event.target )
			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either

		// check if target is a textnode (safari)
		if ( event.target.nodeType == 3 )
			event.target = event.target.parentNode;

		// Add relatedTarget, if necessary
		if ( !event.relatedTarget && event.fromElement )
			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;

		// Calculate pageX/Y if missing and clientX/Y available
		if ( event.pageX == null && event.clientX != null )
		{
			var doc = document.documentElement, body = document.body;
			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
		}

		// Add which for key events
		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
			event.which = event.charCode || event.keyCode;

		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
		if ( !event.metaKey && event.ctrlKey )
			event.metaKey = event.ctrlKey;

		// Add which for click: 1 == left; 2 == middle; 3 == right
		// Note: button is not normalized, so don't use it
		if ( !event.which && event.button )
			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));

		return event;
	},
	//绑定事件
	addEvent:function(type,fn,capture,caller)
	{
		var handle=this.createEventProxy(fn,caller);
		if(this.el.attachEvent)
		{
			this.el.attachEvent('on'+type,handle);
		}
		else if(this.el.addEventListener)
		{
			this.el.addEventListener(type,handle,JBF.isBoolean(capture)?capture:false);
		}
		else
		{
			this.el['on'+type]=handle;
		}
		this.eventHandlers[type]=handle;
		return this;
	},
	//移除事件绑定
	removeEvent:function(type,/*可选*/fn,/*可选*/capture,caller)
	{
		var handle=this.createEventProxy(fn,caller);
		JBF.each(this.eventHandlers,function(v,i,list)
		{
			if(v==type)
			{
				handle=list[v];
				return;
			}
		});
		
		if(this.el.detachEvent)
		{
			this.el.detachEvent('on'+type,handle);
		}
		else if(this.el.removeEventListener)
		{
			this.el.removeEventListener(type,handle,JBF.isBoolean(capture)?capture:false);
		}
		else
		{
			this.el['on'+type]=null;
		}
		delete this.eventHandlers[type];
		return this;
	},
	//绑定多个事件
	addEvents:function(listeners,capture,caller)
	{
		JBF.each(JBF.isObject(listeners)?listeners:{},function(v,i,list)
		{
			this.addEvent(v,list[v],capture,caller);
		},this);
		return this;
	},
	//移除多个事件绑定
	removeEvents:function(listeners,capture,caller)
	{
		JBF.each(JBF.isObject(listeners)?listeners:{},function(v,i,list)
		{
			this.removeEvent(v,list[v],capture,caller);
		},this);
		return this;
	},
	//=addEvent
	on:function(type, handler,capture,caller)
	{
		return this.addEvent(type, handler,capture,caller);
	},
	//=removeEvent
	un:function(type, handler,capture,caller)
	{
		return this.removeEvent(type, handler,capture,caller);
	},
	//未完善
	fireEvent : function(t)
	{
		if(JBF.isIE)
		{
			this.el.fireEvent('on'+t);
		}
		else
		{
			var evt = (document.createEvent("MouseEvents"));  
         	evt.initEvent(t,true,true);
			this.el.dispatchEvent(evt);
			/*http://www.w3school.com.cn/xmldom/met_document_createevent.asp
			HTMLEvents HTMLEvent iniEvent() 
MouseEvents MouseEvent iniMouseEvent() 
UIEvents UIEvent iniUIEvent() 

			*/
		}
	},
	click : function()
	{
		this.fireEvent('click');
		return this;
	},
	focus : function()
	{
		this.el.focus();//fireEvent('focus');
		return this;
	},
	autoTestPwdStrength:function(outResultDivId,minPwdLen)
	{
		var pwd=this.val();
		var strength = 0;
		minPwdLen=JBF.isNumber(minPwdLen)?minPwdLen:6;
		if (pwd.length<minPwdLen && pwd.length>1)
		{
			strength = 1;
		}
		else
		{
			strength = ((pwd.search(/[a-zA-Z]/)!=-1) ? 1 : 0) + ((pwd.search(/[0-9]/)!=-1) ? 1 : 0) + ((pwd.search(/[^A-Za-z0-9_]/)!=-1) ? 1 : 0);
		}
		
		if(!JBF.isEmpty(outResultDivId))
		{
			var spanCss="border:1px solid #ccc;color:#999; border-right:none; padding:2px 10px 0px 10px; margin:0px; float:left;",current="background:#E3F1B8 none repeat scroll 0 0;font-weight:bold;";
			var levL=spanCss+(strength==1?current:''),
				levM=spanCss+(strength==2?current:''),
				levH=spanCss+'border:1px solid #ccc;color:#999;'+(strength==3?current:'');
			var html='<span style="margin:0px; padding:0px;">';
			html+='<span style="'+levL+'">低</span><span style="'+levM+'">中</span>';
			html+='<span style="'+levH+'">高</span>';
			html+='</span>';
			JBF.Dom(outResultDivId).html(html);
		}
		return strength;
	}
};


//元素element 1 
//属性attr 2 
//文本text 3 
//注释comments 8 
//文档document 9 

JBF.apply(JBF.Dom,{  
	//创建浮动DIV
	createFloatDivWrap:function(innerHtml,cssText,id)
	{
		return "<div id='"+(JBF.isEmpty(id)?('JBF-'+(JBF.idSeed++)) :id)+"' style='position:absolute;z-index:2;width:100%;height:100%;left:0;top:0;background:#fff;"+(cssText?cssText:'')+"' >"+innerHtml+"</div><iframe frameborder='0' border='0' style='width:100%;height:100%;position:absolute;z-index:1;left:0;top:0;filter:Alpha(opacity=0);'></iframe>";
	}
		   
});

